package com.example.demo.common.msg.disruptor;/**
 * Created by kete on 2017-12-15.
 */

import com.example.demo.common.msg.DisruptorMessageSender;
import com.example.demo.common.msg.MessageEntitySendHandler;
import com.example.demo.common.msg.MessageEntitySendHandlerFactory;
import com.example.demo.common.msg.MessageSender;
import com.example.demo.common.msg.vo.MessageType;
import com.example.demo.common.persistence.dao.MsgRecordMapper;
import com.example.demo.common.persistence.model.MsgRecord;
import com.example.demo.common.persistence.util.JsonUtil;
import com.example.demo.core.constant.Constants;
import com.lmax.disruptor.dsl.Disruptor;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

/**
 * 作者：kete
 * 创建时间：2017-12-15 14:45
 * 功能描述：
 * 版本：
 */
@SuppressWarnings("SpringJavaAutowiringInspection")
@Configuration
@ConditionalOnProperty(prefix = "guns", name = "mq-open", havingValue = "true")
public class MessageSendConfig {
    private Logger logger = LoggerFactory.getLogger(MessageSendConfig.class);
    public static final String emailQueue="message.email.queue";

    @Autowired
    MsgRecordMapper msgRecordMapper;

    @Autowired
    @Qualifier("jmsQueueTemplate")
    JmsTemplate jmsQueueTemplate;


    //发待办
    private final MessageEntitySendHandler todoMessageEntitySendHandler = (record,receiver,mw)->{
        if(StringUtils.isEmpty(mw.getTodoUrl())) return;
        if(receiver.getUserId() == null) return;
        record.setType(MessageType.TODO.stringValue());
        msgRecordMapper.insert(record);
    };

    //发站内消息
    private final MessageEntitySendHandler siteMessageEntitySendHandler = (record, receiver, mw) -> {
        if(receiver.getUserId() == null) return;

        record.setType(MessageType.SITE.stringValue());
        msgRecordMapper.insert(record);

    };

    //短信
    private final MessageEntitySendHandler smsMessageEntitySendHandler = (record, receiver, mw) -> {
        if(StringUtils.isEmpty(receiver.getMobile())) return;

        record.setType(MessageType.SMS.stringValue());
        record.setIsRead(Constants.MSG_READ);

        msgRecordMapper.insert(record);

    };

    //邮件
    private final MessageEntitySendHandler emailMessageEntitySendHandler = (record, receiver, mw) -> {
        if(StringUtils.isEmpty(receiver.getEmail())) return;

        record.setType(MessageType.EMAIL.stringValue());
        record.setIsRead(Constants.MSG_READ);

        msgRecordMapper.insert(record);
        sendEmail(receiver.getEmail(), mw.getTitle(), mw.getContent(), String.valueOf(record.getId()));
        //recordInitLog(record, jmsMessageId);
    };

    //保存消息发送记录
    private void recordInitLog(MsgRecord record, String jmsMessageId) {

    }

    @Bean
    @ConditionalOnProperty(prefix = "guns", name = "mq-open", havingValue = "true")
    MessageEntitySendHandlerFactory createMessageEntitySendHandlerFactory(){
        return (type)->{
            if (type.getValue() == "0") return siteMessageEntitySendHandler;
            if (type.getValue() == "1") return smsMessageEntitySendHandler;
            if (type.getValue() == "2") return emailMessageEntitySendHandler;
            if (type.getValue() == "3") return todoMessageEntitySendHandler;
            return (record, receiver, mw) -> {/*do nothing */};
        };
    }


    /**
     * 将disruptor 实现的消息发送实现导出为spring bean
     * @param factory
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix = "guns", name = "mq-open", havingValue = "true")
    MessageSender createMessageSender(@Autowired MessageEntitySendHandlerFactory factory){
        Disruptor<MessageEvent> disruptor = new Disruptor<MessageEvent>(MessageEvent::new,256, Executors.defaultThreadFactory());

        MessageEventPublisher publisher = new MessageEventPublisher(disruptor.getRingBuffer());

        DisruptorMessageSender sender = new DisruptorMessageSender();
        sender.setEventPublisher(publisher);
        sender.setHandlerFactory(factory);
        disruptor.handleEventsWith(sender);
        disruptor.start();
        sender.setDisruptor(disruptor);
        return sender;
    }


    private void sendEmail(String email, String title, String content, String recordId) {

        Map<String, String> messageBody = new HashMap<String, String>();
        messageBody.put("type", "email");
        messageBody.put("email", email);
        messageBody.put("title", title);
        messageBody.put("content", content);
        messageBody.put("msgId", recordId);
        messageBody.put("configType", "1");

        String jsonData = JsonUtil.toJSon(messageBody);

        jmsQueueTemplate.send(emailQueue, new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                Message message = session.createTextMessage(jsonData);
                return message;
            }
        });
    }


}
